<?php


namespace app\model;


use app\services\Cart;
use app\services\Logistics;
use app\services\Order;
use think\Exception;
use think\exception\HttpException;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Request;
use think\Model;

class CommodityOrder extends Model
{
    protected $name = "commodity_order";
    protected $autoWriteTimestamp = 'int';
    protected $createTime = 'created_time';


    /**
     * 订单列表
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DbException
     */
    public function OrderList($data)
    {
        $where[] = ['a.user_id', '=', $data['user_id']];
        if ($data['status'] == '0') {
            $data['status'] = [0];
        }
        if (!empty($data['status'])) {
            if ($data['status'] == 2) {
                $data['status'] = [2, 3, 4, 5, 6, 7, 8, 9];
            }

            $where[] = ['a.status', 'in', $data['status']];
        }
        if (!empty($map['search_name'])) {
            $where[] = ['d.goods_name', 'like', "{$map['search_name']}%"];
        }
        $result = Db::name('commodity_order')
            ->alias('a')
            ->field("a.ship_code,a.ship_number,a.id,a.order_sn,a.total,a.postfee,a.num,a.goods_price,a.user_id,a.goods_spec_id,a.address_id,a.status,a.merchant_name,a.merchant_id,a.order_remark,a.order_type,a.buyer_msg,FROM_UNIXTIME(a.created_time,'%Y-%m-%d %h:%i:%s') as created_time,a.updated_time,a.receipt_time,a.end_time,b.goods_sn,b.goods_id,b.goods_name,b.goods_img,b.spec_text,b.spec_ids,b.goods_spec_id,a.return_msg,c.province,c.city,c.county,c.address,d.first_class,d.two_class")
            ->leftJoin('commodity_order_goods b', 'a.id = b.order_id')
            ->leftJoin('address c', 'c.id = a.address_id')
            ->leftJoin('commodity_goods d', 'a.goods_id = d.id')
            ->where($where)
            ->order('a.id desc')
            ->paginate($data['limit'])
            ->toArray();
        return app('json')->json_success('成功', $result);
    }

    /**
     * 下单信息
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function payMsg($data)
    {
        $where = ['user_id' => $data['user_id'], 'is_default' => 1];
        if (!empty($data['address_id'])) {
            $where = ['user_id' => $data['user_id'], 'id' => $data['address_id']];
        }
        $address = Db::name('address')->where($where)->find();
        $data['province'] = $address['province'];
        $result = $this->cartList($data, $data['type'], json_decode($data['order'], true));
        $result['address'] = $address;
        $result['order'] = $data['order'];
        return app('json')->json_success('成功', $result);
    }


    /**
     * 下单
     * @param $data
     * @param int $type 默认1是积分渠道 2.走支付渠道 3.走余额金钱渠道
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function Pay($data, $type = 1)
    {
        if (is_array($data->data['order'])) {
            $orders = $data->data['order'];
        } else {
            $orders = $data->order;
        }
        if (isset($data->data['province'])) {
            $province = $data->data['province'];
        } else {
            $province = $data->address['province'];
        }
        // $province = !isset($data->data['province']) ?: $data->address['province'];
        $order_array = Order::OrderArray($orders, $data->data['address_id'], $province, $data->user_id, $data->data['type'], $type);
        Db::startTrans();
        try {
            switch ($type) {
                case 1:
                    $balance = $data->user->integral;
                    if ($balance < $order_array['total_price']) {
                        Db::rollback();
                        throw new HttpException(500, '余额不足');
                    }
                    break;
                case 3:
                    $balance = $data->user->money;
                    if ($balance < $order_array['total_price']) {
                        Db::rollback();
                        throw new HttpException(500, '余额不足');
                    }
            }

            if ($order_array['area_discern_id'] != '') {
                Db::rollback();
                throw new HttpException(500, '当前选择的地址的商品：' . $order_array['area_discern_id'] . '不发货。请清理后重新下单');
            }
            if (!empty($order_array['list'])) {
                $order = $this->saveAll($order_array['list']);
                $new_arr = array_column($order->toArray(), NULL, 'goods_spec_id');
                foreach ($order_array['list'] as &$v) {
                    foreach ($new_arr as $k => $s) {
                        if (strstr($k, (string)$v['goods_spec_id']) !== false) {
                            $v['order_id'] = $s['id'];
                        }
                    }
                }
                app()->make(CommodityOrderGoods::class)->saveAll($order_array['list']);
                foreach ($order_array['list'] as $item) {
                    Db::name('commodity_goods')->where(['id' => $item['goods_id']])->dec('stock', $item['num'])->update();
                    Db::name('commodity_spec')->where(['goods_spec_id' => $item['goods_spec_id']])->dec('stock', $item['num'])->update();
                }
                $redis_ids = array_column($orders, 'goods_spec_id');
                if ($data->data['type'] == 2) { //下单类型2.购物车下单 3.直接下单
                    Cart::getInstance()->cartDelOne($data->user_id, $redis_ids);
                }
                switch ($type) {
                    case 1:
                        //保存日志信息
                        MoneyLog::SetUserMoney($data->user->id, $data->user->integral, $order_array['total_price'], 1, 2);
                        $data->user->integral -= $order_array['total_price'];
                        $data->user->save();
                        Db::commit();
                        return app('json')->json_success('成功');
                        break;
                    default:
                        Db::commit();
                        return ['order_id' => array_column($order->toArray(), 'id'), 'total_price' => $order_array['total_price']];
                }
            }
            Db::rollback();
            throw new HttpException(500, '购买失败1');
        } catch (\Exception $exception) {
            Db::rollback();
            throw new HttpException(500, '购买失败2' . $exception->getMessage());
        }

    }


    /**
     * 秒杀
     * @param $data
     * @return mixed
     */
    public function Spike($data)
    {
        $result = Order::SpikeStatus($data->user_id, $data->data['goods_number_key'], $data->data['user_queue_key'], $data->data['spike']);
        if ($result['code'] != 1) {
            return app('json')->json_error($result['msg']);
        }
        Db::startTrans();
        try {
            $goods = Db::name('commodity_goods')
                ->alias('a')
                ->leftJoin('commodity_spec b', 'a.id = b.goods_id')
                ->field('a.id,b.goods_spec_id,b.goods_id,b.spec_ids,b.spec_text,a.m_id,a.sn,a.name as goods_name,a.image as goods_img')
                ->where(['a.id' => $data->data['spike']->goods_id])
                ->find();
            $order = array(
                'order_sn' => createdOrderSn(),
                'total' => $data->data['spike']->spike_price,
                'goods_price' => $data->data['spike']->spike_price,
                'goods_id' => $goods['id'],
                'num' => 1,
                'user_id' => $data->user_id,
                'goods_spec_id' => $goods['goods_spec_id'],
                'address_id' => $data->data['address_id'],
                'buyer_msg' => $data->data['goods_msg'],
                'merchant_id' => $goods['m_id'],
                'order_type' => 3,
            );
            $orderModel = app()->make(CommodityOrder::class)->create($order);
            $orderGoods = array(
                'order_id' => $orderModel->id,
                'goods_sn' => $goods['sn'],
                'goods_id' => $goods['id'],
                'goods_name' => $goods['goods_name'],
                'goods_img' => $goods['goods_img'],
                'num' => 1,
                'price' => $data->data['spike']->spike_price,
                'total' => $data->data['spike']->spike_price,
                'spec_ids' => $goods['spec_ids'],
                'spec_text' => $goods['spec_text'],
                'goods_spec_id' => $goods['goods_spec_id'],
            );
            app()->make(CommodityOrderGoods::class)->save($orderGoods);
            //修改库存
            $spike = $data->data['spike'];
            $spike->spike_num -= 1;
            $spike->save();
            //修改用户余额
            $data->user->integral -= $data->data['spike']->spike_price;
            $data->user->save();
            Db::commit();
            return app('json')->json_success('购买成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return app('json')->json_error('购买失败' . $exception->getMessage());
        }

    }


    /**
     * 购物车信息
     * @param array $data
     * @param int $type
     * @param array $order
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function cartList($data, $type = 1, $order = [])
    {
        $cart_list = \app\services\Cart::getInstance()->cartList($data['user_id']);
        if ($type == 2) {
            $spec_ids = array_column($order, 'goods_spec_id');
        } elseif ($type == 3) {
            unset($cart_list);
            $cart_list[$order[0]['goods_spec_id']] = $order[0]['num'];
            $spec_ids = $order[0]['goods_spec_id'];
        } else {
            $spec_ids = array_keys($cart_list);
        }
        if (empty($spec_ids)) {
            return app('json')->json_success('请选择下单的商品');
        }
        $where[] = ['b.channel', '=', $data['cls']];
        $result = Db::name('commodity_spec')
            ->field('a.goods_spec_id,a.goods_id,c.name as merchant_name,c.image as merchant_image,b.m_id,b.name as goods_name,spec_text,a.picture,a.price,b.express_id')
            ->alias('a')
            ->where($where)
            ->leftJoin('commodity_goods b', 'a.goods_id = b.id')
            ->leftJoin('merchant c', 'b.m_id = c.id')
            ->whereIn('a.goods_spec_id', $spec_ids)
            ->select()
            ->toArray();
        $new_arr = array();
        $freights = 0;
        if (!empty($result)) {
            //根据不同商家组装数据
            foreach ($result as &$value) {
                $value['num'] = $cart_list[$value['goods_spec_id']];
                $value['freights'] = 0;
                $value['is_area_discern'] = 0;
                //计算商品是否有加价地区
                if (!empty($data['province'])) {
                    //计算商品是否包邮
                    $delivery = Db::name('commodity_express_delivery')->where(['id' => $value['express_id']])->find();
                    $area_discern = explode(',', $delivery['shipping_address']);
                    if (in_array($data['province'], $area_discern)) {
                        $value['is_area_discern'] = 1;
                    }
                    $markup = Db::name('commodity_express_markup')->where(['d_id' => $value['express_id']])->select()->toArray();
                    $markup = array_column($markup, null, 'area_text');
                    if (array_key_exists($data['province'], $markup)) {
                        $value['freights'] = $markup[$data['province']]['area_price'];
                        $freights += $value['freights'] * $value['num'];
                    }
                }
                $value['total'] = $value['price'] * $value['num'];
                if (!array_key_exists($value['merchant_name'], $new_arr)) {
                    $new_arr[$value['merchant_name']] = ['name' => $value['merchant_name'], 'image' => $value['merchant_image'], 'value' => [$value]];
                } else {
                    array_push($new_arr[$value['merchant_name']]['value'], $value);
                }
            }
        }
        $total_price = array_sum(array_column($result, 'total')) + $freights;
        $total_num = array_sum(array_column($result, 'num'));
        $list = ['list' => array_values($new_arr), 'total_price' => $total_price, 'total_num' => $total_num];
        switch (Request::action()) {
            case 'cartList':
                return app('json')->json_success('成功', $list);
            default:
                return $list;
        }
    }


    /**
     * 订单操作
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function OrderModify($data)
    {
        Db::startTrans();
        try {
            $order = $this->where(['id' => $data['order_id'], 'user_id' => $data['user_id']])->find();
            if (!$order) {
                return app('json')->json_error('订单不存在');
            }
            switch ($data['cls']) {
                case 1:
                    $status = 2;
                    $order->receipt_time = date('Y-m-d H:i:s', time());
                    //增加销量
                    Db::name('commodity_goods')->where('id', $order->goods_id)->inc('sales', $order->num)->update();
                    break;
                case 2:
                    $order->return_msg = $data['return_msg'];
                    $status = 3;
                    break;
                case 3:
                    $order->return_msg = $data['return_msg'];
                    $status = 4;
                    break;
            }
            $order->status = $status;
            Db::name('commodity_order_goods')->where('order_id', $order->id)->update(['status' => $status]);
            $order->save();
            Db::commit();
            return app('json')->json_success('成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return app('json')->json_error('购买失败' . $exception->getMessage());
        }
    }


    /**
     * 抽奖订单生成
     * @param $goods_id
     * @param $user_id
     * @param $address_id
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function LotteryOrder($goods_id, $user_id, $address_id)
    {
        //获取用户默认地址
        $goods = Db::name('commodity_goods')
            ->where(['id' => $goods_id])
            ->find();
        $order = array(
            'order_sn' => createdOrderSn(),
            'total' => 0,
            'goods_price' => $goods['price'],
            'num' => 1,
            'user_id' => $user_id,
            'address_id' => $address_id,
            'merchant_id' => $goods['m_id'],
            'order_type' => 2,
        );
        $orderModel = app()->make(CommodityOrder::class)->create($order);
        $orderGoods = array(
            'order_id' => $orderModel->id,
            'goods_sn' => $goods['sn'],
            'goods_id' => $goods_id,
            'goods_name' => $goods['name'],
            'goods_img' => $goods['image'],
            'num' => 1,
            'price' => $goods['price'],
            'total' => 0,
        );
        app()->make(CommodityOrderGoods::class)->save($orderGoods);
        return true;
    }


    /**
     * 物流信息
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function logistics($data)
    {
        $order = $this->where(['id' => $data['order_id'], 'user_id' => $data['user_id']])->find();
        if (!$order) {
            return app('json')->json_error('订单不存在');
        }
        $result = [];
        if ($order->status == 1) {
            //查看物流
            $juheExpress = app()->make(Logistics::class);
            $results = $juheExpress->getResult(['ship_code' => $order->ship_code, 'ship_number' => $order->ship_number]);
            if ($results != false) {
                $result = $results;
//                $result['image'] = Db::name('express')->where(['code'=>$result->com])->value('')
            }
        }
        return app('json')->json_success('成功', $result);

    }

    /**
     * 修改收货地址
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function OrderAddress($data)
    {
        $address = Address::where(['id' => $data['address_id'], 'user_id' => $data['user_id']])->find();
        if (!$address) {
            return app('json')->json_error('地址不存在');
        }
        $order = $this->where(['id' => $data['order_id'], 'user_id' => $data['user_id']])->find();
        if (!$order || $order->status != 10) {
            return app('json')->json_error('订单不存在');
        }
        $order->address_id = $data['address_id'];
        $order->save();
        return app('json')->json_success('成功');
    }


    /**
     * 支付回调
     * @param $userId
     * @param $remakes
     */
    public static function payDoneOrderCallback($userId, $remakes)
    {
        $nowTime = date('Y-m-d H:i:s', time());
        Db::startTrans();
        try {
            self::where('user_id', $userId)
                ->whereIn('id', explode(',', $remakes))
                ->update(['status' => 0, 'updated_time' => $nowTime]);
            Db::name('commodity_order_goods')->whereIn('order_id', explode(',', $remakes))->update(['status' => 0]);
            Db::commit();
        } catch (\Exception $exception) {
            Db::rollback();
        }
    }
}


